package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.mapper.AdChannelMapper;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.common.aliyun.GreeTextScan;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.exception.CustException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.feigns.wemedia.WemediaFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    //注入wemedia feign
    @Autowired
    WemediaFeign wemediaFeign;
    //注入 artic feign
    @Autowired
    ArticleFeign articleFeign;

    //注入阿里云 文本校验
    @Autowired
    GreeTextScan greeTextScan;

    //注入敏感词 mapper
    @Autowired
    AdSensitiveMapper adSensitiveMapper;

    //注入阿里云 图片校验
    @Autowired
    GreenImageScan greenImageScan;

    //注入 频道 接口
    @Autowired
    AdChannelMapper adChannelMapper;

    @Value("${file.oss.web-site}")
    private String webSite;
    /**
     * 自媒体文章审核
     *
     * @param wmNewsId
     */
    @Override
    public void autoScanByMediaNewsId(Integer wmNewsId) {
        //参数校验
        if (wmNewsId == null) {
            log.error("文章id不能为空！");
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //1  根据文章 内容 id 通过feign 远程调用
        WmNews wmNews = wemediaFeign.findByid(wmNewsId);
        //1.1 校验返回值
        if (wmNews == null) {
            log.error("当前id 对应审核文章不存在,自媒体的id:{}", wmNewsId);
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST); //数据不存在
        }

        //2.判断文章的状态
        //2.1 文章状态=4 && 文章发布时间<=当前时间 人工审核通过，直接保存文章
        if (wmNews.getStatus().equals(WmNews.Status.ADMIN_SUCCESS.getCode()) &&
                wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {

            //2.1  调用方法 保存文章
            saveAppArticle(wmNews);
            return;
        }

        //3 文章状态=8 审核通过 但是发布时间小于等于当前时间，直接保存文章
        if (wmNews.getStatus().equals(WmNews.Status.SUCCESS.getCode())
        && wmNews.getPublishTime().getTime()<=System.currentTimeMillis()
        ){
            //保存 aparticle 文章
            saveAppArticle(wmNews);
            return;
        }

        //4.文章 状态 = 1  未审核
        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())
        ){
            //解析文章 中的 内容
            Map<String,Object> contentAndImagesResult = handleTextAndImages(wmNews);

            //4.1 审核自管理的 敏感词
            boolean isSensitiveScan = handleSensitive((String) contentAndImagesResult.get("content"),wmNews);
            if (!isSensitiveScan) return;


/*
            //4.2 审核文本内容-阿里云
            boolean isTextScan = handleTextScan((String) contentAndImagesResult.get("content"),wmNews);
            if (!isTextScan) return;

            //4.3 审核图片-阿里云
            boolean isImageScan = handleImageScan((List) contentAndImagesResult.get("images"),wmNews);
            if (!isImageScan) return;
*/

            //4.4 如果 发布时间 大于 当前时间 则 修改 文章状态 =8
            if (wmNews.getPublishTime().getTime()>System.currentTimeMillis()){
                updateNews(wmNews, WmNews.Status.SUCCESS.getCode(), "文章审核通过，待发布");
            }
            //5 审核通过，保存文章相关信息（三张表）， 修改文章的状态=9 已发布
            saveAppArticle(wmNews);

        }
    }

    /**
     * 阿里云审核文章内容
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleTextScan(String content, WmNews wmNews) {
        //检验参数
        if (content==null&&wmNews==null){
            log.error("阿里云 图片检验 参数 不能为空 ！");
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        boolean flag = true;
        try {
            Map map = greeTextScan.greeTextScan(content);
            // 审核失败
            if (map.get("suggestion").equals("block")) {
                flag = false;
                updateNews(wmNews, WmNews.Status.FAIL.getCode(), "阿里云审核-文章内容中包含违规内容");
            }

            // 人工审核
            if (map.get("suggestion").equals("review")) {
                flag = false;
                updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "需要人工审核");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(" aliyun handleTextScan error:{} ",e);
            flag = false;
            updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "阿里云审核失败，转入人工审核");
        }
           return flag;

    }
    /**
     * 阿里云-图片审核
     * @param images
     * @param wmNews
     * @return
     */
    private boolean handleImageScan(List<String> images, WmNews wmNews) {
        //检验参数
        if (images==null && wmNews == null){
            log.error("阿里云 图片检验 参数 不能为空 ！");
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }

        boolean flag =true;
        try{
            //图片去重
           images= images.stream().distinct().collect(Collectors.toList());
           Map map=greenImageScan.imageUrlScan(images);

           //判断 检验 返回值 如果为  block 则 校验失败
            if (map.get("suggestion").equals("block"))  {
                flag =false;
                updateNews(wmNews,WmNews.Status.FAIL.getCode(),"阿里云图片违规！");
            }

           //人工审核
           if (map.get("suggestion").equals("review")){
               flag=false;
               updateNews(wmNews,WmNews.Status.ADMIN_AUTH.getCode(), "需要人工审核");
           }


        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
            updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "需要人工审核");
        }
        return flag;
    }

    //校验自管理 敏感词
    private boolean handleSensitive(String content, WmNews wmNews) {
        //判断文章内容 和  wmNews对象 是否为空
        if (content ==null && wmNews==null){
            log.error("自管理 敏感词 检验 文章 不能为空 ！");
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }

        boolean flag =true;
        //1.数据库中 获取 敏感词
        List<String> sensitives = adSensitiveMapper.findAllSensitive();
        //2.初始化 敏感词 数据库
        SensitiveWordUtil.initMap(sensitives);
        //3.校验
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(content);
        //4.判断 是否存在 敏感词
        if (stringIntegerMap.size()>0){
            //有 敏感词 设置 flag 为 false
            updateNews(wmNews, WmNews.Status.FAIL.getCode(), "文章中包含自管理敏感词"+stringIntegerMap);
            flag = false;
        }
        return flag;
    }

    /**
     * 解析文章中文本和图片（封面图片）
     * @param wmNews
     * @return
     */
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        //1.获取文章 内容
        String content = wmNews.getContent();

        //2.校验文章 内容 判断是否 为空 长度 是否  小于 10000
        if (StringUtils.isNotBlank(content)&&content.length()<10000){
            //3.将 文章 解析成 为 map 集合
            List<Map> contentList = JSON.parseArray(content, Map.class);//

            //4.创建 builder 存放 text 文本
            StringBuilder sb = new StringBuilder();
            sb.append(wmNews.getTitle()).append("__hwl__");

            //5.创建 list 集合 存放 转换 成 string 的 图片 路径
            ArrayList<String> images = new ArrayList<>();

            //6.循环遍历 content 文章内容
            for (Map<String, String> map : contentList) {

                //7.判断 type 是 text 还是 images
                //文本
                if (map.get("type").equals("text")){
                    //7.1
                    sb.append(map.get("value"));
                    // 处理拼接出现敏感词问题
                    sb.append("__hmtt__");
                }
                //图片
                if (map.get("type").equals("image")){
                    images.add(map.get("value"));
                }
            }
            //8.解析封面 图片
            String wmNewsImages = wmNews.getImages();
            if (StringUtils.isNotBlank(wmNewsImages)){
                String[] split = wmNewsImages.split(",");
                for (String url : split) {
                    images.add(webSite+url);
                }
            }

            //9.返回结果
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("content", sb.toString());
            resultMap.put("images", images);

            return resultMap;
        }


        return null;
    }


    /**
     * 保存apArticle文章  审核通过文章
     *
     * 远程发起调用  保存文章三张表数据
     * @param wmNews
     */
    private void saveAppArticle(WmNews wmNews) {
        log.info("执行保存文章方法！");

        //保存文章
        ResponseResult result = saveArticle(wmNews);
        //根据 返回 结果  code 判断 是否执行 成功
        if (result.getCode()!=0){
            CustException.cust(AppHttpCodeEnum.ARTICLE_SAVE_ERROR);
        }

        Object data = result.getData();
        wmNews.setArticleId((Long) data);

        updateNews(wmNews,WmNews.Status.PUBLISHED.getCode(),"审核通过，已发布");
    }

    /**
     * 修改自媒体文章
     * @param wmNews 文章
     * @param status 状态
     * @param reason 拒绝理由
     */
    private void updateNews(WmNews wmNews, Short status, String reason) {
        //修改wmNews 状态 理由
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        ResponseResult responseResult = wemediaFeign.updateWmNews(wmNews);

        if (responseResult.getCode()!=0){
            CustException.cust(AppHttpCodeEnum.WEMEDIA_UPDATE_ERROR);
        }
    }

    private ResponseResult saveArticle(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();
        //1.使用Bean工具类 调用 copy方法 复制 同名 属性 的值
        BeanUtils.copyProperties(wmNews,articleDto);
        //2.判断 ad 是否为空 不为空 则  将 wmnews id 设置给 dto
        if (wmNews.getArticleId() !=null){
            articleDto.setId(wmNews.getArticleId());
        }

        //3.设置作者信息
        WmUser wmUser = wemediaFeign.findWmUserById(wmNews.getUserId());
        //3.1 校验 是否 为空
        if (wmUser != null){
            //给 dto 设置 名称
            articleDto.setAuthorName(wmUser.getName());
        }

        //4.设置 频道 信息]
        AdChannel adChannel = adChannelMapper.selectById(wmNews.getChannelId());
        //4.1 判断 是否 为空
        if (adChannel != null){
            articleDto.setChannelId(adChannel.getId());
            articleDto.setChannelName(adChannel.getName());
        }

        //5.文章布局
        articleDto.setLayout(wmNews.getType());
        articleDto.setFlag((byte) 0);
        articleDto.setCreatedTime(new Date());
        articleDto.setOrigin(true);

        // 返回值 包含article 文章ID
        return articleFeign.saveArticle(articleDto);
    }

}